package server

/**
 * 控制格式：
 * 		登录： LOGIN/:NAME/:TEST001
 *		控制： TEMP/:TEST001/:52
 *		状态： STATUS/:TEST001/:ON
 */

import (
	"fmt"
	"github.com/patrickmn/go-cache"
	"log"
	"net"
	"os"
	"smartHomeNode/v1/base"
	"strings"
)

type Udp struct {
	Base
}

/**
 * 启动 TCP 连接服务
 */
func (ctx *Base) UdpRun() {
	fmt.Println("Starting udp server ...")
	ctx.udpServer()
}

/**
 * 驱动Udp 服务
 */
func (ctx *Base) udpServer() {
	addr, err := net.ResolveUDPAddr("udp", UDPSERVER)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	conn, err := net.ListenUDP("udp", addr)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	defer conn.Close()

	for {
		data := make([]byte, 64)
		_, rAddr, err := conn.ReadFromUDP(data)
		if err != nil {
			fmt.Println(err)
			continue
		}
		strData := ""
		for _, strDataList := range data {
			if strDataList != 0 {
				strData += string(strDataList)
			}
		}
		if strings.Contains(strData, "/:") {
			info := strings.Split(strData, "/:")
			if len(info) == 3 {
				time := ctx.NowTime()
				call := time[0] + ":" + time[1] + ":" + time[2]
				fmt.Println(call + " Call: " + strData)
				ctx.checkUdpCode(info, conn, rAddr)
			} else {
				fmt.Println("udp Server Error message: " + strData)
			}
		} else {
			fmt.Println("udp Server Error data ??? is: " + strData)
		}
	}
}

/**
 * 检查客户端消息
 */
func (ctx *Base) checkUdpCode(info []string, conn *net.UDPConn, rAddr *net.UDPAddr) {
	code := "FAIL"
	switch info[0] {
	case "TEMP":
		ctx.updateTempStatus(info[1], info[2])
		code = "SUCCESS"
	case "HUM":
		ctx.updateHumStatus(info[1], info[2])
		code = "SUCCESS"
	}
	_, err := conn.WriteToUDP([]byte(strings.ToUpper(code)), rAddr)
	if err != nil {
		log.Printf("Response message error: %v\n", err)
	}
}

/**
 * 处理温度上报
 */
func (ctx *Base) updateTempStatus(name string, code string) {
	time := ctx.NowDateTimeMap()
	t := "&" + time["m"] + "/" + time["d"] + " " + time["H"] + ":" + time["i"]
	base.TempData.Set(name, code+t, cache.DefaultExpiration)
	data, found := base.DeviceAlias.Get(name)
	if found {
		base.DeviceAlias.Set(name, data, cache.DefaultExpiration)
	}
}

/**
 * 处理湿度上报
 */
func (ctx *Base) updateHumStatus(name string, code string) {
	time := ctx.NowDateTimeMap()
	t := "&" + time["m"] + "/" + time["d"] + " " + time["H"] + ":" + time["i"]
	base.HumData.Set(name, code+t, cache.DefaultExpiration)
	data, found := base.DeviceAlias.Get(name)
	if found {
		base.DeviceAlias.Set(name, data, cache.DefaultExpiration)
	}
}
